// protocol 协议
#pragma once
#include <iostream>
#include <string>

// Request->计算机输入->序列化&反序列化
// Response->计算机输出->序列化&反序列化

// 约定好各个字段的含义，本质就是约定好协议！
// client -> server
// 如何要做序列化和反序列化：
// 1. 我们自己写(怎么做) ---> 往往不具备很好的扩展性
// 2. 使用现成的方案(这个是我们要写的) ---> json -> jsoncpp

// request 请求 oper 操作
class Request
{
public:
	/**********Request**************/
	Request(int x, int y, char oper) : _x(x), _y(y), _oper(oper) {}
	~Request() {}
	/**********成员函数**************/
	// serialize 序列化
	std::string Serialize()
	{
		return std::to_string(_x) + ' ' + std::to_string(_y) + ' ' + _oper + '#';
	}
	// deserialize 反序列化
	int Deserialize(std::string& in)
	{
		std::string lo_value;
		std::string lo_code;
		int flag = 0;
		for (char it : in)
		{
			if (it == ' ')
			{
				++flag;
				continue;
			}
			if (it == '#')
			{
				break;
			}
			switch (flag)
			{
			case 0:
				lo_value.push_back(it);
				break;
			case 1:
				lo_code.push_back(it);
				break;
			default:
				break;
			}
		}
		int loint_code = std::stoi(lo_code);
		_value = std::stoi(lo_value);
		return loint_code;
	}
	/**********Get**************/
	int Get()
	{
		return _value;
	}

private:
	int _x;
	int _y;
	char _oper; // + - * / % -> _x _oper _y -> 10 + 20
	int _value;
};

// response 应答 code 代码
class Response
{
public:
	/**********Response**************/
	Response() : _value(0), _code(-1) {}
	~Response() {}
	/**********成员函数**************/
	void Task(const int x, const int y, const char oper)
	{
		switch (oper)
		{
		case '+':
			_value = x + y;
			break;
		case '-':
			_value = x - y;
			break;
		case '*':
			_value = x * y;
			break;
		case '/':
			if (y == 0)
			{
				_code = 1;
				return;
			}
			_value = x / y;
			break;
		case '%':
			if (y == 0)
			{
				_code = 1;
				return;
			}
			_value = x % y;
			break;
		default:
			_code = -1;
			return;
			break;
		}
		_code = 0;
		return;

	}
	std::string Serialize()
	{
		return std::to_string(_value) + ' ' + std::to_string(_code) + '#';
	}
	void Deserialize(std::string& in)
	{
		std::string lo_x;
		std::string lo_y;
		std::string lo_oper;
		int flag = 0;
		for (char it : in)
		{
			if (it == ' ')
			{
				++flag;
				continue;
			}
			if (it == '#')
			{
				break;
			}
			switch (flag)
			{
			case 0:
				lo_x.push_back(it);
				break;
			case 1:
				lo_y.push_back(it);
				break;
			case 2:
				lo_oper.push_back(it);
				break;
			default:
				break;
			}
		}
		int loint_x = std::stoi(lo_x);
		int loint_y = std::stoi(lo_y);
		Task(loint_x, loint_y, lo_oper.c_str()[0]);
	}

private:
	int _value; // 运算结果，无法区分清楚应答是计算结果，还是异常值
	int _code;  // 0:sucess, 1,2,3,4->不同的运算异常的情况
};